#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <arpa/inet.h>
#define QUIT_STR "quit"

int main (int argc, const char* argv[])
{
    //创建套接字
    int fd = socket(AF_INET, SOCK_DGRAM, 0);
    if (fd == -1) 
    {
	perror("socket error\n");
	exit(1);
    }

    // 允许绑定地址快速重用 
    int b_reuse = 1;
    setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &b_reuse, sizeof (int));

    //fd绑定本地的IP和端口
    struct sockaddr_in serv;
    memset(&serv, 0, sizeof(serv));
    serv.sin_family = AF_INET;
    serv.sin_port = htons(8765);
    serv.sin_addr.s_addr = htonl(INADDR_ANY);
    int ret = bind(fd, (struct sockaddr*)&serv, sizeof(serv));
    if(ret == -1)
    {
	perror("bind error\n");
	exit(1);
    }

    //通信
    struct sockaddr_in client;
    socklen_t cli_len = sizeof(client);
    char buf[1024];
    while(1)
    {
	bzero(buf, sizeof(buf));
	int recvlen = recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr*)&client, &cli_len);
	printf(">>>>>>>>>>>>>>>.\n");
	if(recvlen == -1)
	{
	    perror("recvfrom error\n");
	    exit(1);
	}

	char ip[64] = {0};
	printf("client ip:%s, port:%d\n", 
		inet_ntop(AF_INET, &client.sin_addr.s_addr, ip, sizeof(ip)),
		ntohs(client.sin_port));
	printf("recv buf:%s\n", buf);

	if (!strncasecmp (buf, QUIT_STR, strlen (QUIT_STR))) {  //用户输入了quit字符
	    printf ("Client %s:%d is exiting!\n", ip, ntohs(client.sin_port));
	}

    }

    close(fd);

    return 0;
}
